package org.dromara.system.utils;

import cn.hutool.core.util.ObjectUtil;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.*;
import java.util.*;

public class PdfToMapConverter {
    public static List<Map> handlePdfTable(InputStream inputStream)  throws IOException{
        List<Map> list = new ArrayList<>();

        //在初始化 PdfDocument 对象时加载源 PDF 文件
        PdfDocument sourceDoc = new PdfDocument(inputStream);
        // 总页数
        int pageCount = sourceDoc.getPages().getCount();
        // 此工具仅能解析前十页，全部解析需付费,故将pdf拆分十页的子pdf
        if(pageCount>10){
            int fileNumber = pageCount/10;
            if(pageCount%10 > 0){
                fileNumber = fileNumber+1;
            }
            for(int i=0;i<fileNumber;i++){
                PdfDocument pdf = new PdfDocument();
                // 分页从0开始
                if(i==fileNumber-1){
                    // 最后一个子文件
                    pdf.insertPageRange(sourceDoc, i*10,pageCount-1);
                }else{
                    pdf.insertPageRange(sourceDoc, i*10,i*10+9);
                }
                List<Map> sonData = handlePdfData(pdf);
                list.addAll(sonData);
            }

        }else{
            list = handlePdfData(sourceDoc);
        }
        // 还要考虑多个表格
        return list;
    }

    /**
     * 获取单个pdf表格数据
     * @param pdf
     * @return
     */
    public static List<Map> handlePdfData(PdfDocument pdf){
        List<Map> list = new ArrayList<>();
        //创建PdfTableExtractor类的对象
        PdfTableExtractor extractor = new PdfTableExtractor(pdf);
        // 因存在pdf分页之后，列表的数据会在新一页有表头，故要进行判断新一页第一行数据，是表头数据就要删掉
        // 故存一下第一页第一行的第一字段，如果下一页相同就跳过  表头重复情况
        String firstColumnData = "";
        //遍历子pdf每一页
        for (int page = 0; page < pdf.getPages().getCount(); page++)
        {
            //提取页面中的表格存入PdfTable[]数组
            PdfTable[] tableLists = extractor.extractTable(page);
            if (tableLists != null && tableLists.length > 0)
            {
                //遍历表格
                for (PdfTable table : tableLists)
                {
                    int row = table.getRowCount();//获取表格行
                    int column = table.getColumnCount();//获取表格列
                    for (int j = 0; j < row;j++)
                    {
                        Map map = new LinkedHashMap();
                        for (int k = 0; k < column; k++)
                        {
                            //获取表格中的文本内容
                            String text = table.getText(j, k);
                            text = text.replaceAll("\\s*|\r|\n|\t","");
                            if(page == 0 && j ==0 && k == 0){
                                firstColumnData = text;
                            }else if(j ==0 && k == 0 && firstColumnData.equals(text)){
                                break;
                            }
                            map.put(k,text);
                        }
                        if(ObjectUtil.isNotEmpty(map)){
                            list.add(map);
                        }
                    }
                    Map map = new LinkedHashMap();
                    map.put(0,"FC_ZT_666");
                    list.add(map);
                }
            }
        }
        return list;
    }

    /**
     * 获取项目编号
     * @param file
     * @return
     */
    public static String extractTextFromPDF(File file) {
        PDDocument document = null;
        try {
            document = PDDocument.load(file);
            PDFTextStripper pdfStripper = new PDFTextStripper();
            return pdfStripper.getText(document);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (document != null) {
                try {
                    document.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
